package com.panda.cn.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.panda.cn.config.exception.RestfulException;
import com.panda.cn.entity.SysDeptEntity;
import com.panda.cn.entity.SysMenuEntity;
import com.panda.cn.mapper.SysMenuMapper;
import com.panda.cn.service.SysMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统菜单服务impl
 *
 * @author Yanmh
 * @date 2022/09/20
 */
@Slf4j
@Service
@DS("sys")
public class SysMenuServiceImpl implements SysMenuService {
    
    @Resource
    private SysMenuMapper sysMenuMapper;
    
    /**
     * 查询所有菜单编码
     * @param name
     * @return
     */
    @Override
    public List all(String name) {
        // 1、查询所有的部门数据
        LambdaQueryWrapper<SysMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(name)) {
            queryWrapper.like(SysMenuEntity::getName, name);
        }
    
        queryWrapper.eq(SysMenuEntity::getIsDelete, "N")
                .orderByAsc(SysMenuEntity::getId);
        List<SysMenuEntity> allMenu = sysMenuMapper.selectList(queryWrapper);
        List<String> menuCodes = new ArrayList<>();
        allMenu.stream().forEach(menuEntity -> {
            menuCodes.add(menuEntity.getCode());
        });
        
        return menuCodes;
    }
    
    /**
     * 列表
     *
     * @param params
     * @return
     */
    @Override
    public List tree(JSONObject params) {
        // 1、查询所有的菜单数据
        LambdaQueryWrapper<SysMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenuEntity::getIsDelete, "N")
                .orderByAsc(SysMenuEntity::getSort);
        if (StrUtil.isNotEmpty(params.getStr("type"))) {
            queryWrapper.eq(SysMenuEntity::getType, params.getStr("type"));
        }
        List<SysMenuEntity> allMenu = sysMenuMapper.selectList(queryWrapper);
        
        // 2、数据进行递归查询
        // 获取根部门
        List<SysMenuEntity> treeList = allMenu.stream().filter(menuEntity -> {
            // 模糊检索
            if (ObjUtil.isNotNull(params) && StrUtil.isNotEmpty(params.getStr("name"))) {
                return menuEntity.getName().contains(params.getStr("name"));
            }
            // 全量
            if (ObjUtil.isNotNull(menuEntity) && "root".equals(menuEntity.getParentCode())) {
                recursion(allMenu, menuEntity);
                return true;
            }
            return false;
        }).collect(Collectors.toList());
        return treeList;
    }
    
    /**
     * 添加菜单信息
     *
     * @param params
     * @return
     */
    @Override
    public Long insert(SysMenuEntity params) {
        // 判断是否为空
        if(StrUtil.isEmpty(params.getName()))
            throw new RestfulException("名称或不能为空");
        // 查看是不是存在相同的编码和名称
        LambdaQueryWrapper<SysMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenuEntity::getName, params.getName());
        Integer count = sysMenuMapper.selectCount(queryWrapper);
        if(count>0)
            throw new RestfulException("名称存在相同");
    
        // 当前时间
        DateTime nowDateTime = DateUtil.parse(DateUtil.now());
        params.setCreateTime(nowDateTime);
        params.setUpdateTime(nowDateTime);
        // 创建唯一uuid
        String code = IdUtil.randomUUID();
        params.setCode(code);
        // 添加
        sysMenuMapper.insert(params);
        return params.getId();
    }
    
    /**
     * 修改菜单信息
     *
     * @param params
     * @return
     */
    @Override
    public Long update(SysMenuEntity params) {
        // 判断是否为空
        if (ObjUtil.isEmpty(params.getId()))
            throw new RestfulException("唯一编码缺失");
        if(StrUtil.isEmpty(params.getName()))
            throw new RestfulException("名称不能为空");
        // 查看是不是存在相同的编码和名称
        LambdaQueryWrapper<SysMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(SysMenuEntity::getId, params.getId())
                .and(i -> i.eq(SysMenuEntity::getName, params.getName()));
    
        Integer count = sysMenuMapper.selectCount(queryWrapper);
        if(count>0)
            throw new RestfulException("名称存在相同");
    
        // 当前时间
        DateTime nowDateTime = DateUtil.parse(DateUtil.now());
        params.setUpdateTime(nowDateTime);
        // 添加
        sysMenuMapper.updateById(params);
    
        return params.getId();
    }
    
    /**
     * 删除菜单信息
     *
     * @param params
     * @return
     */
    @Override
    public Long remove(List<Long> params) {
        // 验证
        if (ObjUtil.isNull(params) || params.size() == 0)
            throw new RestfulException("唯一编码缺失");
        //  更新的编码
        LambdaQueryWrapper<SysMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysMenuEntity::getId, params);
    
        // 更新的数据
        SysMenuEntity entity = new SysMenuEntity();
        entity.setIsDelete("Y");
    
        int update = sysMenuMapper.update(entity, queryWrapper);
        return Long.valueOf(update);
    }
    
    /**
     * 递归
     *
     * @param allMenu 所有菜单
     * @param entity  实体
     * @return {@link List}<{@link SysMenuEntity}>
     */
    private void recursion(List<SysMenuEntity> allMenu, SysMenuEntity entity) {
        // 要找的数据中 父级菜单的编码
        String code = entity.getCode();
        
        List<SysMenuEntity> childList = allMenu.stream()
                .filter(menuEntity -> {
                    // 有匹配项目
                    if (ObjUtil.isNotNull(menuEntity) && code.equals(menuEntity.getParentCode())) {
                        recursion(allMenu, menuEntity);
                        return true;
                    }
                    return false;
                }).collect(Collectors.toList());
        if (ObjUtil.isNotNull(childList) && childList.size() > 0)
            entity.setChildren(childList);
    }
}
